package com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.properties;

import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.psi.PsiParameter;
import com.intellij.ui.JBColor;
import com.neuronbit.businessflow.intellij.dialog.MethodParamValueSourceTreeChooseDialog;
import com.neuronbit.businessflow.intellij.editor.UIDesignerBundle;
import com.neuronbit.businessflow.intellij.editor.swing.editor.RadComponent;
import com.neuronbit.businessflow.intellij.editor.swing.editor.RadJavaMethodComponent;
import com.neuronbit.businessflow.intellij.editor.swing.editor.RadStatefulTaskComponent;
import com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.InplaceContext;
import com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.Property;
import com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.PropertyEditor;
import com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.PropertyRenderer;
import com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.renderers.LabelPropertyRenderer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * The type Method param property.
 */
public class StateCheckerMethodParamProperty extends Property<RadStatefulTaskComponent, String> {
    private final Project project;
    private final PropertyRenderer myRenderer;
    @NotNull
    private final PsiParameter parameter;
    private final String paramIndex;

    private final PropertyEditor myEditor = new MyPropertyEditor();

    /**
     * Instantiates a new Method param property.
     *
     * @param parent     the parent
     * @param project    the project
     * @param parameter  the parameter
     * @param paramIndex the param index
     */
    public StateCheckerMethodParamProperty(@NotNull Property parent, Project project, @NotNull PsiParameter parameter, String paramIndex) {
        super(parent, parameter.getName() + ": " + ReadAction.compute(()->parameter.getType().getPresentableText()));
        this.project = project;
        this.myRenderer = new LabelPropertyRenderer();
        this.parameter = parameter;
        this.paramIndex = paramIndex;
    }

    @Override
    public @NotNull PropertyRenderer<String> getRenderer() {
        return myRenderer;
    }

    @Override
    public @Nullable PropertyEditor<String> getEditor() {
        return myEditor;
    }

    @Override
    public String getValue(RadStatefulTaskComponent component) {
        return component.getStateCheckerParamValue(paramIndex);
    }

    @Override
    protected void setValueImpl(RadStatefulTaskComponent component, String value) throws Exception {
        component.setStateCheckerParamValue(paramIndex, value);
    }

//    @Override
//    public Property @NotNull [] getChildren(RadJavaMethodComponent component) {
//        return new Property[]{
//                new ParamNameProperty(this, component.getProject(), this.parameter),
//                new ClassToBindProperty4(this, component.getProject(), this.parameter, "type"),
//                new VariableToBindProperty(this, component.getProject(), this.parameter, paramIndex, "value")
//        };
//    }

    @Override
    public boolean needRefreshPropertyList() {
        return true;
    }

    private class MyPropertyEditor extends PropertyEditor {
        private final TextFieldWithBrowseButton myTf = new TextFieldWithBrowseButton();
        private RadComponent component;

        /**
         * Instantiates a new My property editor.
         */
        MyPropertyEditor() {
            //myTf.setText(UIDesignerBundle.message("client.properties.configure"));
            myTf.getTextField().setEditable(false);
            myTf.getTextField().setBorder(null);
            myTf.getTextField().setForeground(JBColor.foreground());
            myTf.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    showClientPropertiesDialog();
                }
            });
        }

        private void showClientPropertiesDialog() {
            MethodParamValueSourceTreeChooseDialog dialog2 = new MethodParamValueSourceTreeChooseDialog(project,
                    component.getDelegee(),
                    parameter.getName(),
                    parameter.getType());
            if (dialog2.showAndGet()) {
                String result = dialog2.getSelected();
                if (result != null) {
                    myTf.setText(result);
                }
            }
//            ConfigureClientPropertiesDialog dlg = new ConfigureClientPropertiesDialog(myProject);
//            dlg.show();
//            if (dlg.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
//                dlg.save();
//                fireValueCommitted(true, false);
//            }
        }

        @Override
        public Object getValue() throws Exception {
            final String value = myTf.getText();
            return value.replace('$', '.'); // PSI works only with dots
        }

        @Override
        public JComponent getComponent(final RadComponent component, final Object value, final InplaceContext inplaceContext) {
            this.component = component;
            if (null != value) {
                myTf.setText(value.toString());
            } else {
                myTf.setText(UIDesignerBundle.message("client.properties.configure"));
            }
            return myTf;
        }

        @Override
        public void updateUI() {
            SwingUtilities.updateComponentTreeUI(myTf);
        }
    }
}
